using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using System.Threading;

namespace MiniAnimation
{
    public delegate UniTask UniTaskFunc();
    public delegate Task TaskFunc();
    public abstract class SequenceNode
    {
        protected TaskCompletionSource<bool> tcs;
        //用于等待任务完成
        public Task<bool> Task => tcs.Task;
        //用于取消任务
        protected CancellationTokenSource Cts;
        public event System.Action OnCompleted;
        protected bool isPause = false;
        protected List<SequenceNode> children = new List<SequenceNode>();
        protected bool isKilled = false;
        public SequenceNode()
        {
            tcs = new TaskCompletionSource<bool>();
            Cts = new CancellationTokenSource();
            isKilled=false;
        }
        public void AddSubChildren(SequenceNode node)
        {
            children.Add(node);
        }
        public async UniTask Excute()
        {
            if (!isKilled)
            {
                Resume();
                //同时执行join进来的所有节点
                if (children.Count > 0)
                {
                    UniTask[] tasks = new UniTask[children.Count + 1];
                    for (int i = 0; i < children.Count; i++)
                    {
                        tasks[i] = children[i].Excute();
                    }
                    tasks[children.Count] = OnExcute();
                    //全部执行完毕后，执行下一个节点
                    await UniTask.WhenAll(tasks);
                }
                else
                {
                    await OnExcute();
                }
                OnCompleted?.Invoke();
            }
            tcs.TrySetResult(true);

        }
        protected abstract UniTask OnExcute();
        public virtual void Pause()
        {
            isPause = true;
        }
        public virtual void Resume()
        {
            isPause = false;
        }

        public virtual void Kill()
        {
            isKilled=true;
            for (int i = 0; i < children.Count; i++)
            {
                children[i].Kill();
            }
            if (tcs.Task.IsCompleted == false)
            {
                tcs.TrySetResult(false);
            }
            Cts?.Cancel();
        }
    }
}